package com.fcscs.cservice.service.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fcscs.core.common.ErrorEnums;
import com.fcscs.core.service.FcsManager;
import com.fcscs.cservice.dao.GuestProfileDao;
import com.fcscs.cservice.domain.ContactInfo;
import com.fcscs.cservice.domain.GuestProfile;
import com.fcscs.cservice.domain.GuestProfileDetail;
import com.fcscs.cservice.domain.model.ContactInfoView;
import com.fcscs.cservice.domain.model.GuestProfileFindView;
import com.fcscs.cservice.domain.model.GuestProfileView;
import com.fcscs.cservice.domain.model.GuestProfileViewForFile;
import com.fcscs.cservice.domain.validator.GuestProfileValidators;
import com.fcscs.cservice.service.GuestProfileManager;

@Service("guestProfileManager")
public class GuestProfileManagerImpl extends FcsManager implements GuestProfileManager {

	@Autowired
	private GuestProfileDao gpDao;
	
	private static Logger LOGGER = Logger.getLogger(GuestProfileManagerImpl.class);

	public List<GuestProfileFindView> findGuestProfile(long propId, String firstName, String lastName, String roomNo, String phoneNo,
			String mobileNo, String memberNo, int start, int resultCnt, boolean inHouseGuestOnly) {
		return gpDao.findGuestProfile(propId, firstName, lastName, roomNo, phoneNo, mobileNo, memberNo, start, resultCnt, inHouseGuestOnly);
	}

	public int findGuestProfileCnt(long propId, String firstName, String lastName, String roomNo, String phoneNo,
			String mobileNo, String memberNo, boolean inHouseGuestOnly) {
		return gpDao.findGuestProfileCnt(propId, firstName, lastName, roomNo, phoneNo, mobileNo, memberNo, inHouseGuestOnly);
	}

	@Override
	public <E extends GuestProfile> E getGuestProfile(long id, Class<E> cls) {
		return gpDao.getGuestProfile(id, cls);
	}

	@Override
	public <E extends GuestProfile> E updateGuestProfile(E guestProfile) {
		ErrorEnums err = new GuestProfileValidators.GuestProfileValidator().validate(guestProfile, guestProfile.getId() == null);
		if (err != null) {
			LOGGER.debug(err);
			return null;
		}
		transferBaseVals(guestProfile, guestProfile, guestProfile.getId() == null);
		return gpDao.updateGuestProfile(guestProfile);
	}

	@Override
	public ContactInfo getContactInfo(long id) {
		return gpDao.getContactInfo(id);
	}

	@Override
	public ContactInfo updateContactInfo(ContactInfo contactInfo) {
		ErrorEnums err = new GuestProfileValidators.ContactInfoValidator().validate(contactInfo, contactInfo.getId() == null);
		if (err != null) {
			LOGGER.debug(err);
			return null;
		}
		transferBaseVals(contactInfo, contactInfo, contactInfo.getId() == null);
		return gpDao.updateContactInfo(contactInfo);
	}

	@Override
	public GuestProfileView getGuestProfileView(long id) {
		GuestProfileView gpv = gpDao.getGuestProfileView(id);
//		loadGuestProfileViewDetail(gpv);
		return gpv;
	}

	@Override
	public GuestProfileViewForFile getGuestProfileViewForFile(long id) {
		GuestProfileViewForFile gpv = gpDao.getGuestProfileViewForFile(id);
//		loadGuestProfileViewDetail(gpv);
		return gpv;
	}

//	private void loadGuestProfileViewDetail(GuestProfileView gpv) {
//		if (gpv == null) {
//			return;
//		}
//		long gpId = gpv.getGuestProfileViewId();
//		gpv.setPrefCodes(gpDao.getPrefCodesString(gpId));
//		gpv.setSpecialCodes(gpDao.getSpecialCodesString(gpId));
//		gpv.setVipCodes(gpDao.getVIPCodesString(gpId));
//	}

	@Override
	public GuestProfileView updateGuestProfileView(GuestProfileView gpView) {
		if (gpView == null) {
			return gpView;
		}
		long orgId = gpView.getOrgId();
		Long propId = gpView.getPropertyId();

		Long guestProfileId = gpView.getGuestProfileViewId();
		boolean gpIsNew = guestProfileId == null;
		GuestProfileDetail gp = null;
		if (gpIsNew) {
			gp = new GuestProfileDetail();
		} else {
			gp = gpDao.getGuestProfile(guestProfileId, GuestProfileDetail.class);
		}
		gp = transGPFromGPView(gpView, gp, gpIsNew);
//		gp.setPrimaryContactInfoId(ciView == null ? null : ciView.getContactInfoViewId());

		ContactInfoView ciView = gpView.getContactInfo();
		ContactInfo ci = gp.getContactInfo();
		boolean ciIsNew = false;
		if (ciView != null) {
			if (ci == null) {
				ciIsNew = true;
				ci = new ContactInfo();
			}
			ci = transCIFromCIView(orgId, propId, ciView, ci, ciIsNew);
			ci = updateContactInfo(ci);
			if (ci == null) {
				return null;
			}
			ciView = transCIViewFromCI(ci, ciView, ciIsNew);
		}

		gp.setContactInfo(ci);
		gp = updateGuestProfile(gp);
		if (gp == null) {
			return null;
		}
		gpView = transGPViewFromGP(gp, gpView, gpIsNew);

		gpView.setContactInfo(ciView);
		if ((ciIsNew || gpIsNew) && ciView != null) {
			gpDao.updateGuestContactInfo(gpView.getGuestProfileViewId(), ciView.getContactInfoViewId());
		}
		return gpView;
	}

	private GuestProfileView transGPViewFromGP(GuestProfile gp, GuestProfileView gpView, boolean isNew) {
		if (gp == null || gpView == null) {
			return gpView;
		}
		gpView.setGuestProfileViewId(gp.getId());
		gpView.setFirstName(gp.getFirstName());
		gpView.setLastName(gp.getLastName());
		gpView.setTitleId(gp.getTitleId());
		gpView.setGenderMale(gp.getGenderMale());
		gpView.setLanguageId(gp.getLanguageId());
		gpView.setNationalityId(gp.getNationalityId());
		gpView.setEmail(gp.getEmail());
		gpView.setMobile(gp.getMobile());
		gpView.setSpecialCodes(gp.getSpecialCodes());
		gpView.setNotes(gp.getNotes());
		gpView.setCreated(gp.getCreated());
		gpView.setUpdated(gp.getUpdated());
		gpView.setProfileNumber(gp.getProfileNumber());
		gpView.setNoOfVisit(gp.getNoOfVisit());
		gpView.setPrefCodes(gp.getPrefCodes());
		gpView.setVipCodes(gp.getVipCodes());
		return gpView;
	}

	private <E extends GuestProfile> E transGPFromGPView(GuestProfileView gpView, E gp, boolean isNew) {
		if (gp == null || gpView == null) {
			return gp;
		}
		gp.setOrgId(gpView.getOrgId());
		gp.setPropertyId(gpView.getPropertyId());
		gp.setFirstName(gpView.getFirstName());
		gp.setLastName(gpView.getLastName());
		gp.setTitleId(gpView.getTitleId());
		gp.setGenderMale(gpView.getGenderMale());
		gp.setLanguageId(gpView.getLanguageId());
		gp.setNationalityId(gpView.getNationalityId());
		gp.setEmail(gpView.getEmail());
		gp.setMobile(gpView.getMobile());
		gp.setSpecialCodes(gpView.getSpecialCodes());
		gp.setNotes(gpView.getNotes());
		if (isNew) {
			gp.setProfileNumber(null);
			gp.setNoOfVisit(0);
			gp.setPrefCodes(gpView.getPrefCodes());
			gp.setVipCodes(gpView.getVipCodes());
		}
		return gp;
	}

	private ContactInfoView transCIViewFromCI(ContactInfo ci, ContactInfoView ciView, boolean isNew) {
		if (ci == null || ciView == null) {
			return ciView;
		}
		ciView.setContactInfoViewId(ci.getId());
		ciView.setType(ci.getType());
		ciView.setAddress(ci.getAddress());
		ciView.setCity(ci.getCity());
		ciView.setTown(ci.getTown());
		ciView.setCountryId(ci.getCountryId());
		ciView.setStateId(ci.getStateId());
		ciView.setPhone1(ci.getPhone1());
		ciView.setPhone2(ci.getPhone2());
		ciView.setZipPostal(ci.getZipPostal());
		return ciView;
	}

	private ContactInfo transCIFromCIView(long orgId, Long propId, ContactInfoView ciView, ContactInfo ci, boolean isNew) {
		if (ci == null || ciView == null) {
			return ci;
		}
		ci.setType(ciView.getType());
		ci.setAddress(ciView.getAddress());
		ci.setCity(ciView.getCity());
		ci.setTown(ciView.getTown());
		ci.setCountryId(ciView.getCountryId());
		ci.setStateId(ciView.getStateId());
		ci.setPhone1(ciView.getPhone1());
		ci.setPhone2(ciView.getPhone2());
		ci.setZipPostal(ciView.getZipPostal());
		if (isNew) {
			ci.setOrgId(orgId);
			ci.setPropertyId(propId);
			ci.setPmsTypeEnum(ci.getTypeEnum().getPmsType());
		}
		return ci;
	}
}
